package com.fiberhome.nas.feature.common.ext

import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.runtime.MutableState
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.hapticfeedback.HapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.round
import androidx.compose.ui.unit.toIntRect

/**
 * 照片网格拖动处理函数
 *
 * @param lazyGridState 照片网格状态
 * @param haptics 触觉反馈
 * @param selectedIds 选中的照片ID集合
 * @param autoScrollSpeed 自动滚动速度
 * @param autoScrollThreshold 自动滚动阈值
 */
fun Modifier.photoGridDragHandlerInt(
    lazyGridState: LazyGridState,
    haptics: HapticFeedback,
    selectedIds: MutableState<Set<Int>>,
    autoScrollSpeed: MutableState<Float>,
    autoScrollThreshold: Float,
    updateSelectedItems: (Set<Int>) -> Unit,
) = pointerInput(Unit) {
    fun LazyGridState.gridItemKeyAtPosition(hitPoint: Offset): Int? =
        layoutInfo.visibleItemsInfo.find { itemInfo ->
            itemInfo.size.toIntRect().contains(hitPoint.round() - itemInfo.offset)
        }?.key as? Int

    var initialKey: Int? = null
    var currentKey: Int? = null
    detectDragGestures(
        onDragStart = { offset ->
            lazyGridState.gridItemKeyAtPosition(offset)?.let { key ->
                haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
                initialKey = key
                currentKey = key
                if (!selectedIds.value.contains(key)) {
                    selectedIds.value += key
                } else {
                    selectedIds.value -= key
                }
                updateSelectedItems(selectedIds.value)
            }
        },
        onDragCancel = { initialKey = null; autoScrollSpeed.value = 0f },
        onDragEnd = { initialKey = null; autoScrollSpeed.value = 0f },
        onDrag = { change, _ ->
            if (initialKey != null) {
                val distFromBottom =
                    lazyGridState.layoutInfo.viewportSize.height - change.position.y
                val distFromTop = change.position.y
                autoScrollSpeed.value = when {
                    distFromBottom < autoScrollThreshold -> autoScrollThreshold - distFromBottom
                    distFromTop < autoScrollThreshold -> -(autoScrollThreshold - distFromTop)
                    else -> 0f
                }

                lazyGridState.gridItemKeyAtPosition(change.position)?.let { key ->
                    if (currentKey != key) {
                        selectedIds.value = selectedIds.value
                            .minus(initialKey!!..currentKey!!)
                            .minus(currentKey!!..initialKey!!)
                            .plus(initialKey!!..key)
                            .plus(key..initialKey!!)
                        updateSelectedItems(selectedIds.value)
                        currentKey = key
                    }
                }
            }
        }
    )
}


/**
 * 照片网格拖动处理函数
 *
 * @param lazyGridState 照片网格状态
 * @param haptics 触觉反馈
 * @param selectedIds 选中的照片ID列表
 * @param ids 所有照片ID列表
 * @param autoScrollSpeed 自动滚动速度
 * @param autoScrollThreshold 自动滚动阈值
 */
fun Modifier.photoGridDragHandlerString(
    lazyGridState: LazyGridState,
    haptics: HapticFeedback,
    selectedIds: MutableState<Set<String>>,
    updateSelectedItems: (Set<String>) -> Unit,
    autoScrollSpeed: MutableState<Float>,
    autoScrollThreshold: Float
) = pointerInput(Unit) {
    var initialKey: String? = null
    var currentKey: String? = null
    var selected: Boolean = false

    fun LazyGridState.gridItemKeyAtPosition(hitPoint: Offset): String? =
        layoutInfo.visibleItemsInfo.find { itemInfo ->
            itemInfo.size.toIntRect().contains(hitPoint.round() - itemInfo.offset)
        }?.key as? String

    detectDragGestures(
        onDragStart = { offset ->
            lazyGridState.gridItemKeyAtPosition(offset)?.let { key ->
                haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
                initialKey = key
                currentKey = key
                if (selectedIds.value.contains(key)) {
                    selectedIds.value - key
                    selected = false
                } else {
                    selectedIds.value + key
                    selected = true
                }
                updateSelectedItems(selectedIds.value)
            }
        },
        onDragCancel = { initialKey = null; autoScrollSpeed.value = 0f },
        onDragEnd = { initialKey = null; autoScrollSpeed.value = 0f },
        onDrag = { change, _ ->
            if (initialKey != null) {
                val distFromBottom =
                    lazyGridState.layoutInfo.viewportSize.height - change.position.y
                val distFromTop = change.position.y
                autoScrollSpeed.value = when {
                    distFromBottom < autoScrollThreshold -> autoScrollThreshold - distFromBottom
                    distFromTop < autoScrollThreshold -> -(autoScrollThreshold - distFromTop)
                    else -> 0f
                }

                // 获取当前拖动位置的String类型ID
                lazyGridState.gridItemKeyAtPosition(change.position)?.let { key ->
                    if (currentKey != key) {
                        // 获取所有可见项的ID和索引映射
                        val allItemIds = lazyGridState.layoutInfo.visibleItemsInfo
                            .sortedBy { it.index }
                            .mapNotNull { it.key as? String }
                        // 查找起始项和当前项在列表中的位置
                        val startIndex = allItemIds.indexOf(initialKey)
                        val xxx = allItemIds.indexOf(currentKey)
                        val currentIndex = allItemIds.indexOf(key)
                        if (startIndex != -1 && currentIndex != -1) {
                            // 根据索引范围选择ID
                            val changeIds = if (startIndex <= currentIndex) {
                                allItemIds.subList(startIndex, currentIndex + 1)
                            } else {
                                allItemIds.subList(currentIndex, startIndex + 1)
                            }

                            if (selected) {
                                selectedIds.value + changeIds
                            } else {
                                selectedIds.value - changeIds
                            }
                            updateSelectedItems(selectedIds.value)
                            currentKey = key
                        }
                    }
                }
            }
        }
    )
}